package java学习.第17章_反射机制;

import org.apache.commons.jexl3.*;
import org.bouncycastle.util.encoders.UTF8;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import javax.tools.SimpleJavaFileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.io.IOException;
import java.util.Arrays;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class StringCodeToExecutable {
    public static void main(String[] args) throws Exception {
        只能简单的();

    }

    private static void 只能简单的() {
        try {
            Map<String, Object> map = new HashMap<>(16){{
                put("年龄", 14);
                put("姓名", "张蛟龙");
            }};
            String expression = "年龄 > 18";
            Object code = convertToCode(expression, map);
            System.out.println(code); // true
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Object convertToCode(String jexlExp, Map<String, Object> map) {
        // 创建或检索引擎
        JexlEngine jexl = new JexlBuilder().create();
        // 创建一个表达式
        JexlExpression e = jexl.createExpression(jexlExp);
        // 创建上下文并添加数据
        JexlContext jc = new MapContext();
        for (String key : map.keySet()) {
            jc.set(key, map.get(key));
        }
        // 得到结果
        final Object result = e.evaluate(jc);
        return result;
    }
    private static void 模拟java() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        String code = "public class HelloWorld { public static void main(String[] args) { System.out.println(\"Hello, World!\"); } }";

        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        JavaFileObject file = new JavaSourceFromString("HelloWorld", code);
        Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file);

        // 编译源代码
        if (compiler.getTask(null, null, null, Arrays.asList("-source", "17"), null, compilationUnits).call()) {
            // 加载编译后的类
            Class<?> cls = Class.forName("HelloWorld");
            // 反射执行main方法
            Method mainMethod = cls.getMethod("main", String[].class);
            mainMethod.invoke(null, new String[] {});
        } else {
            System.out.println("编译失败");
        }
    }

    // 内存中的Java源代码
    static class JavaSourceFromString extends SimpleJavaFileObject {
        final String code;

        JavaSourceFromString(String name, String code) {
            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
            this.code = code;
        }

        @Override
        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
            return code;
        }
    }
}